#include <iostream>
#include <string>
#include <pthread.h>
#include <unistd.h>
#include <mutex>

class Ticket
{
private:
    int tickets;
    //下面两个锁用法类似
    pthread_mutex_t mtx; //原生线程库 系统级别的锁
    //std::mutex mymtx;    // C++ 语言级别的锁
public:
    Ticket()
        : tickets(1000)
    {
        //初始化这把锁，属性设置为nullptr
        pthread_mutex_init(&mtx, nullptr);
    }

    bool GetTicket()
    {
        bool flag = true;
        //加锁
        pthread_mutex_lock(&mtx);
        //mymtx.lock();

        //抢票
        if (tickets > 0)
        {
            usleep(1000); // 1ms
            std::cout << "我是[" << pthread_self() << "] 我要抢的票是：" << tickets << std::endl;
            tickets--;
        }
        else // tickets <= 0，说明没票了
        {
            std::cout << "没票了" << std::endl;
            flag = false;
        }

        //解锁
        pthread_mutex_unlock(&mtx);
        //mymtx.unlock();

        return flag;
    }

    ~Ticket()
    {
        pthread_mutex_destroy(&mtx);
    }
};

// 抢票逻辑,5个线程同时抢
void *ThreadRoutine(void *args)
{
    Ticket *t = (Ticket *)args;

    while (true)
    {
        //有票返回的就是true，否则是false
        if (!t->GetTicket())
        {
            break;
        }
    }
}

int main()
{
    // new一个票的类对象
    Ticket *t = new Ticket();
    pthread_t tid[5];
    for (int i = 0; i < 5; i++)
    {
        int *id = new int(i);
        pthread_create(tid + i, nullptr, ThreadRoutine, (void *)t);
    }

    for (int i = 0; i < 5; i++)
    {
        pthread_join(tid[i], nullptr);
    }
    return 0;
}